(ns lensfield.webapp.servlet
   (:use [compojure.control]
         [compojure.html]
         [compojure.http.helpers]
         [compojure.http.middleware]
         [compojure.http.routes]
         [compojure.http.servlet]
         [lensfield.triplestore]
         [lensfield.webapp.helpers]
         [lensfield.webapp.sparql])
   (:require [lensfield.defaults :as dft]
             [lensfield.file-utils :as futils]
             [lensfield.webapp.config :as config])
   (:import (java.io File))
   (:gen-class
      :extends javax.servlet.http.HttpServlet))

(defn url [path]
   (str config/*context* path))

(defn styles
   "Return HTML to include CSS stylesheets."
   [& styles]
   (for [style styles]
      (include-css (url style))))
    
(def header [:br [:h1 "My NMR shift calculation results"]])
(def footer [:hr [:a "Contact me"]])

(defn layout
   [title & body]
   (html 
      (doctype :xhtml-strict)
      [:html
         [:head
            [:title title]
            [:meta {:http-equiv "Content-type" :content "text/html; charset=utf-8"}]
            [:link {:rel "alternate" :type "application/atom+xml" :title "Atom archive feed" :href "http://localhost:8080/nmr-calc-example/atom/feed.xml"}]
            (styles "/blueprint/screen.css" "/blueprint/ie.css" "/blueprint/plugins/fancy-type/screen.css")]
         [:body
            [:div {:id "container" :class "container"}
               [:div {:id "header" :class "span-24 last"}
                  header]
               [:hr]
               [:div {:id "container" :class "container"}
                  body]
               [:div {:id "footer" :class "span-24 last"}
                  footer]]]]))

(defn front-page
   [req]
   (let [fl (File. (get-webapp-dir req) "/data")
         html-filenames (filter #(. % endsWith ".html")
                           (map #(.getName %) 
                              (filter #(.isFile %) (file-seq fl))))
         file-links (for [nm html-filenames]
                       [:a {:href (url (str "/data/" nm))} (. nm substring 0 (. nm indexOf ".")) [:br]])]
      (layout "Front page" 
         [:p "This webapp contains the results of my <sup>1</sup>H NMR shift calculations using Gaussian."]
         [:a {:href (url "/query.html")} "Perform SPARQL Query"]
         [:br] [:br] [:br]
         [:div
            [:h3 "Structure summaries"]
            file-links]
         [:br] [:br])))

(defn query-page
   []
   (layout "SPARQL query" 
      [:br]
      [:h3 "SPARQL Query"]
      (form-to [:post (url "/sparql-endpoint")]
         [:p (text-area :query "")
             [:br]
             (submit-button "submit")])))
               
(defn serve-resource
   "Gets the webapp context from the provided request (req) and prepends 
   it to the relative path (rp) provided.  Returns an absolute file path."
   [req rp]
   (let [fl (File. (get-webapp-dir req) rp)]
      (cond 
         (.isFile fl)
            fl
         (.isDirectory fl)
            (find-index-file fl))))

(defroutes lf-webapp
   (POST "/sparql-endpoint"
      (let [ts-dir (str (get-webapp-dir request) "/triple_store")
            query-str (params :query)]
         (println ts-dir)
         [{:headers {"Content-Type" "text/xml"}} (sparql-query ts-dir query-str)]))
   (GET "/*"
      (or (serve-resource request (params :*)) :next))
   (GET "/query.html"
      (query-page))
   (GET "/index.html"
      (front-page request))
   (GET "/"
      (front-page request)))
   (ANY "*"
      (page-not-found))
      
(decorate lf-webapp
    (with-context config/*context*)) 

(defservice lf-webapp)
